package com.example.nacosprovider.Config;

import com.example.nacosprovider.service.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

@Configuration
@EnableRedisHttpSession
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService myUserDetailsService;
    @Autowired
    //会话注册表
    private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
    //@Autowired
    ////会话注册表
    //private SpringSessionBackedSessionRegistry redisSessionRegistry;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/static/**","/templates/**","/updateHeadshotPath").permitAll() // 指定 URL 无需保护。
                .anyRequest() .authenticated()// 其他请求都必须认证
                .and()
                .formLogin()
                .loginPage("/login").permitAll() //设置登录界面url
                .loginProcessingUrl("/user/login") // 设置哪个是登录的 url。
                .defaultSuccessUrl("http://localhost:8071/forum/luntan",true)
                .and()
                .csrf().disable()
                .formLogin()
                .and()
                //进行会话管理
                .sessionManagement()
                .invalidSessionUrl("/login")
                //最大并发会话数,设置单个用户允许同时在线的最大会话数,如果没有额外配置,重新登录的会话会踢掉旧的会话.
                .maximumSessions(1)
                //当设置值为true时防止同一用户再次登录
                .maxSessionsPreventsLogin(false)
                //使用session提供的会话注册表
                .sessionRegistry(sessionRegistry());
    }
    //自定义登录验证流程函数
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //String password = passwordEncoder.encode("123");
        //auth.inMemoryAuthentication().withUser("lucy").password(password).roles("admin");
        auth.userDetailsService(myUserDetailsService).passwordEncoder(password()); //设置自定义密码验证的类
    }
    @Bean
    PasswordEncoder password() {
        return new BCryptPasswordEncoder();
    }

    //Session注册表Bean，实现session集群管理
    //@Bean
    //public SpringSessionBackedSessionRegistry sessionRegistry(){
    //    return new SpringSessionBackedSessionRegistry<>(sessionRepository);
    //}
    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
}
